package pokpok.action;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import pokpok.dao.JoueurDAO;
import pokpok.dao.ResultatDAO;
import pokpok.dao.TournoiDAO;
import pokpok.domaine.Joueur;
import pokpok.domaine.JoueurStat;
import pokpok.domaine.Resultat;
import pokpok.domaine.Tournoi;
import pokpok.service.ResultatDateComparator;
import pokpok.service.Util;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.opensymphony.xwork2.ActionSupport;

public class JoueurAction extends ActionSupport {

	/**
	 * 
	 */
	private static final long serialVersionUID = -7429759453523069767L;

	private List<Joueur> joueurs;
	private List<JoueurStat> joueursStat;

	private String nom;
	private String prenom;
	private String pseudo;

	private Joueur joueur;
	private String keyJoueur;

	private boolean error;
	private String messageError;

	private JoueurStat joueurStat;

	private Map<String, Integer> courbeNetData;

	private Integer saison;
	private List<Integer> saisons;

	public String init() {
		JoueurDAO jDAO = new JoueurDAO();
		joueurs = jDAO.findAll();
		return SUCCESS;
	}

	public String validerCreer() {
		nom = Util.removeAccent(nom);
		prenom = Util.removeAccent(prenom);
		pseudo = Util.removeAccent(pseudo);
		if ("".equals(nom) && "".equals(prenom) && "".equals(pseudo)) {
			error = true;
			messageError = "Il faut indiquer au moins un champ !";
			return INPUT;
		} else {
			joueur = new Joueur(nom, prenom, pseudo);
			JoueurDAO jDAO = new JoueurDAO();
			jDAO.save(joueur);
			return SUCCESS;
		}
	}

	public String supprimer() {
		JoueurDAO jDAO = new JoueurDAO();
		ResultatDAO rDAO = new ResultatDAO();
		Key key = KeyFactory.stringToKey(keyJoueur);
		joueur = jDAO.findById(key);
		List<Resultat> resultats = rDAO.findByJoueur(joueur);
		if (resultats != null && !resultats.isEmpty()) {
			error = true;
			messageError = "Erreur : le joueur fait partie d'au moins un tournoi ("
					+ resultats.size() + " tournois)";
			joueurs = jDAO.findAll();
			return ERROR;
		} else {
			jDAO.delete(joueur);
			joueurs = jDAO.findAll();
			return SUCCESS;
		}
	}

	public String modifierInit() {
		JoueurDAO jDAO = new JoueurDAO();
		Key key = KeyFactory.stringToKey(keyJoueur);
		joueur = jDAO.findById(key);
		nom = joueur.getNom();
		prenom = joueur.getPrenom();
		pseudo = joueur.getPseudo();
		return SUCCESS;
	}

	public String validerModifier() {
		nom = Util.removeAccent(nom);
		prenom = Util.removeAccent(prenom);
		pseudo = Util.removeAccent(pseudo);
		if ("".equals(nom) && "".equals(prenom) && "".equals(pseudo)) {
			error = true;
			messageError = "Il faut indiquer au moins un champ !";
			return INPUT;
		} else {
			Joueur newValue = new Joueur(nom, prenom, pseudo);
			JoueurDAO jDAO = new JoueurDAO();
			Key key = KeyFactory.stringToKey(keyJoueur);
			joueur = jDAO.findById(key);
			joueur = jDAO.update(joueur, newValue);
			return SUCCESS;
		}
	}

	public String stats() {
		initSaisons();
		JoueurDAO jDAO = new JoueurDAO();
		joueurs = jDAO.findAll();
		joueursStat = new ArrayList<JoueurStat>();
		for (Joueur joueur : joueurs) {
			List<Resultat> resultats = getResultats(joueur, saison);
			if (resultats.size() != 0) {
				joueursStat.add(new JoueurStat(joueur, resultats, false));
			}
		}
		return SUCCESS;
	}

	public String info() {
		initSaisons();
		JoueurDAO jDAO = new JoueurDAO();
		joueur = jDAO.findById(KeyFactory.stringToKey(keyJoueur));
		List<Resultat> resultats = getResultats(joueur, saison);
		joueurStat = new JoueurStat(joueur, resultats, true);

		courbeNetData = new LinkedHashMap<String, Integer>();

		Collections.sort(resultats, new ResultatDateComparator());

		int net = 0;
		Tournoi t = null;
		String key = null;
		for (Resultat resultat : resultats) {
			t = resultat.getTournoi();
			key = new SimpleDateFormat("dd/MM/yyyy").format(t.getDate());
			net = net + resultat.getGain();
			net = net - t.getBuyin();
			if (resultat.isAddon()) {
				net = net - t.getAddon();
			}
			net = net - (resultat.getNbRecaves() * t.getRecave());
			courbeNetData.put(key, net);
		}

		Resultat[] array = new Resultat[resultats.size()];
		int i = 0;
		for (Resultat resultat : resultats) {
			array[i++] = resultat;
		}
		return SUCCESS;
	}

	private List<Resultat> getResultats(Joueur joueur, Integer saison) {
		ResultatDAO rDAO = new ResultatDAO();
		List<Resultat> allResultats = rDAO.findByJoueur(joueur);
		if (saison == 0) {
			return allResultats;
		} else {
			List<Resultat> retour = new ArrayList<Resultat>();
			for (Resultat resultat : allResultats) {
				Integer s = resultat.getTournoi().getSaison();
				if (s != null && s.equals(saison)) {
					retour.add(resultat);
				}
			}
			return retour;
		}
	}

	private void initSaisons() {
		TournoiDAO tDAO = new TournoiDAO();
		List<Tournoi> all = tDAO.findAll();
		saisons = new ArrayList<Integer>();
		for (Tournoi tournoi : all) {
			if (tournoi.getSaison() != null
					&& !saisons.contains(tournoi.getSaison())) {
				saisons.add(tournoi.getSaison());
			}
		}
		if (saisons.size() == 0) {
			saisons.add(1);
		}
		Collections.sort(saisons);
		if (saison == null) {
			saison = saisons.get(saisons.size() - 1);
		}
	}

	public List<Joueur> getJoueurs() {
		return joueurs;
	}

	public void setJoueurs(List<Joueur> joueurs) {
		this.joueurs = joueurs;
	}

	public String getNom() {
		return nom;
	}

	public void setNom(String nom) {
		this.nom = nom;
	}

	public String getPrenom() {
		return prenom;
	}

	public void setPrenom(String prenom) {
		this.prenom = prenom;
	}

	public String getPseudo() {
		return pseudo;
	}

	public void setPseudo(String pseudo) {
		this.pseudo = pseudo;
	}

	public Joueur getJoueur() {
		return joueur;
	}

	public void setJoueur(Joueur joueur) {
		this.joueur = joueur;
	}

	public boolean isError() {
		return error;
	}

	public void setError(boolean error) {
		this.error = error;
	}

	public String getMessageError() {
		return messageError;
	}

	public void setMessageError(String messageError) {
		this.messageError = messageError;
	}

	public String getKeyJoueur() {
		return keyJoueur;
	}

	public void setKeyJoueur(String keyJoueur) {
		this.keyJoueur = keyJoueur;
	}

	public List<JoueurStat> getJoueursStat() {
		return joueursStat;
	}

	public void setJoueursStat(List<JoueurStat> joueursStat) {
		this.joueursStat = joueursStat;
	}

	public JoueurStat getJoueurStat() {
		return joueurStat;
	}

	public void setJoueurStat(JoueurStat joueurStat) {
		this.joueurStat = joueurStat;
	}

	public Map<String, Integer> getCourbeNetData() {
		return courbeNetData;
	}

	public void setCourbeNetData(Map<String, Integer> courbeNetData) {
		this.courbeNetData = courbeNetData;
	}

	public Integer getSaison() {
		return saison;
	}

	public void setSaison(Integer saison) {
		this.saison = saison;
	}

	public List<Integer> getSaisons() {
		return saisons;
	}

	public void setSaisons(List<Integer> saisons) {
		this.saisons = saisons;
	}

	public String getSaisonLib() {
		if (saison == null || saison == 0) {
			return "Toutes saisons";
		} else {
			return "Saison " + saison;
		}
	}

}
